<?php
/**
 *  💡 免责声明：本软件不得用于商业用途，仅做学习交流
 *  ⚠️ 权利声明：本软件由版权人提供产品技术支持
 *  📅 项目编号：NX2025-0135
 */
use App\Utils\OrderNumberGenerator;
use Illuminate\Support\Arr;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\Log;

function formatDate($date)
{
    $separator = '-';
    // 替换所有可能的分隔符为指定符号
    $normalized = preg_replace('/[.\/年月日]+/', $separator, $date);
    // 去除首尾的分隔符
    $normalized = trim($normalized, $separator);
    // 处理连续的多个分隔符
    $normalized = preg_replace('/' . preg_quote($separator, '/') . '+/', $separator, $normalized);
    $date = $normalized;
    try {
        $date = Carbon::createFromFormat('Y-m-d', $date)->format('Y-m-d');
    } catch (\Exception $exception) {
        $date = sprintf('%s-%s', date('Y-m'), $normalized);
        $date = Carbon::createFromFormat('Y-m-d', $date)->format('Y-m-d');
    }
    return $date;
}
function isTwoDimensional(array $array): bool
{
    if (empty($array)) {
        return false;
    } // 空数组不视为二维数组

    foreach ($array as $item) {
        if (! is_array($item)) {
            return false; // 存在非数组元素，直接返回 false
        }
    }
    return true; // 所有元素均为数组
}
function arrayToKeyValueString(array $array, string $separator = ', '): string
{
    $pairs = [];
    foreach ($array as $key => $value) {
        $pairs[] = "{$key}:{$value}";
    }
    return implode($separator, $pairs);
}
function genOrderNumber($prefix = null, $length = 10)
{
    if ($prefix) {
        return $prefix . OrderNumberGenerator::generate($length);
    }
    return OrderNumberGenerator::generate($length);
}
function childrenCalc($children)
{
    $total = 0;
    $ids = [];
    foreach ($children as $child) {
        if (! isset($child['children'])) {
            return [$child['total'], $ids];
        }

        array_push($ids, collect($child['children'])->pluck('user_id'));

        $total = bcadd(childrenCalc($child['children']), $child['total'], 2);
    }
    return [$total, $ids];
}

if (! function_exists('CheckRangeDate')) {
    function CheckRangeDate($arr): ?string
    {
        $a = collect($arr);
        $last = null;
        $msg = null;
        $a->values()->each(function ($v, $k) use (&$last, $a, &$msg) {
            if ($v['_remove_'] ?? 0 == 1) {
                return;
            }
            if ($k == 0) {
                if ($v['startTime'] !== '00:00:00') {
                    $msg = "必须以00:00:00开始 第{$k}时间段";
                    return;
                }
                $last = $v['endTime'];
            } else {
                if ($last != $v['startTime']) {
                    $msg = "必须以{$last}做为此段开始时间 第{$k}时间段";
                    return;
                }

                if ($k == $a->count() - 1) {
                    if ($v['endTime'] != '23:59:59') {
                        $msg = "必须以23:59:59作为最终时间 第{$a->count()}时间段";
                        return;
                    }
                }
                $last = $v['endTime'];
            }
        });
        return $msg;
    }
}

if (! function_exists('responses')) {
    /**
     * @param $data
     * @param $code
     * @param $options
     * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\Routing\ResponseFactory|\Illuminate\Http\Response
     */
    function responses($data = [], $code = 1, $options = null)
    {
        $opt = [
            'message' => null,
            'language' => null,
        ];
        if ($options) {
            $opt = array_merge($opt, $options);
        }

        $respones = new \App\Utils\Response();
        if (isset($opt['token'])) {
            $respones->setToken($opt['token']);
        }

        return $respones->response($data, $code, $opt['message'], $opt['language']);
    }
}

if (! function_exists('comparison')) {
    function comparison(string $str, string $s): bool
    {
        return strtolower(substr($str, 0, 1)) == strtolower($s);
    }
}
function dg($data)
{
    app(\Barryvdh\Debugbar\LaravelDebugbar::class)->info($data);
}

function Debugging($message, $context = [])
{
    if (env('APP_DEBUG') == true) {
        if ($context  instanceof \Illuminate\Support\Collection) {
            $context = $context->toArray();
        }
        Log::channel('dubug_log')->debug($message, $context);
    }
}
function getAdminId()
{
    $user = Admin::user();
    if (filled($user)) {
        return $user->getKey();
    }
    return 0;
}

/**
 * 根据值查找二维数组中的子数组.
 * *
 * * @param array $haystack 被搜索的二维数组
 * * @param mixed $needle 要查找的值
 * * @param bool $strict 是否启用严格模式（类型检查）
 * * @return array|null 返回匹配的子数组，未找到返回 null
 */
function findSubArrayByValue(array $haystack, $needle, bool $strict = false): ?array
{
    foreach ($haystack as $item) {
        foreach ($item as $value) {
            if ($strict ? $value === $needle : $value == $needle) {
                return $item;
            }
        }
    }
    return null;
}

/**
 * 在二维数组中查找完全匹配的一维数组.
 * @param array $needle 要查找的一维数组
 * @param array $haystack 目标二维数组
 * @parm  array $ignore   忽略的key
 * @return array|false 找到返回匹配项，否则返回 false
 */
function searchArrayInMulti(array $needle, array $haystack, array $ignore = [])
{
    foreach ($haystack as $key => $item) {
        // 严格比较键值对（顺序、类型、数量完全一致）
        if (count($ignore) != 0) {
            $tempitem = Arr::except($item, $ignore);
            $needle = Arr::except($needle, $ignore);
        }
        if ($tempitem === $needle) {
            return [
                $key,
                $item,
            ];
        }
    }
    return false;
}
function toDateTimeString($v, $flag = 0)
{
    if (intval($v) == 0) {
        return $flag;
    }
    return now()->setTimestamp($v)->toDateTimeString();
}

function toTimestamp($v)
{
    if (blank($v)) {
        return 0;
    }
    return now()->setDateTimeFrom($v)->timestamp;
}

function minuteTurnCharacter($minutes)
{
    $hours = floor($minutes / 60); // 计算小时数
    $minutes = $minutes % 60; // 计算剩余的分钟数
    $days = floor($hours / 24); // 计算天数
    $hours = $hours % 24; // 计算剩余的小时数

    $result = '';

    if ($days > 0) {
        $result .= $days . '天';
    }

    if ($hours > 0) {
        $result .= $hours . '小时';
    }

    if ($minutes > 0) {
        $result .= $minutes . '分钟';
    }

    if ($result == '') {
        $result = '0分钟';
    }
    return $result;
}

if (! function_exists('my_trans_field')) {
    function my_trans_field($field, $path = null, $locale = null)
    {
        $trans = app('admin.translator');
        $trans->setPath($path);
        return $trans->transField($field, $locale);
    }
}

if (! function_exists('asPublic')) {
    function asPublic($path, $secure = null)
    {
        return app('url')->asset("public/{$path}", $secure);
    }
}

if (! function_exists('splitAmountByPercentage')) {
    /**
     * 将金额按百分比分割为两部分（高精度计算）.
     *
     * @param string $amount 总金额（字符串形式传入，避免浮点精度问题）
     * @param float $percentage 第一个部分的百分比（0-100）
     * @param int $scale 计算精度（小数位数）
     * @throws InvalidArgumentException 当参数无效时抛出异常
     * @return array 包含两部分金额的数组 ['part1' => ..., 'part2' => ...]
     */
    function splitAmountByPercentage($amount, $percentage, $scale = 2)
    {
        // 参数验证
        if (! is_numeric($amount) || ! is_numeric($percentage)) {
            throw new InvalidArgumentException('金额和百分比必须是数字');
        }

        if ($percentage < 0 || $percentage > 100) {
            throw new InvalidArgumentException('百分比必须在0到100之间');
        }

        // 转换为字符串确保精度
        $amount = (string) $amount;
        $percentage = (string) $percentage;

        // 计算第一部分金额
        $part1 = bcmul($amount, bcdiv($percentage, '100', $scale + 2), $scale);

        // 计算第二部分金额（总金额减去第一部分）
        $part2 = bcsub($amount, $part1, $scale);

        return [
            'a' => $part1,
            'b' => $part2,
            'percentage_used' => $percentage,
        ];
    }
}
